#-*- coding:utf-8 -*-

from UserList import UserList

class DataRow(object):
    """Wrapper for db result(tuple). Support for d[index] or d['column'] access
    
    Read only object.
    """
    def __init__(self, rs, column_map):
        """
        rs: db result, which are cursor return.
        column_map: {column_name: index, ...}
        """
        self._data = rs
        self._column_map = column_map
        
    def __repr__(self): return repr('DataRow: %s' % (self._data,)) + repr(self._column_map)

    def __getitem__(self, key):
        if not isinstance(key, (int, long)):
            key = self._column_map[key]
        return self._data[key]
    
    def __len__(self):
        return len(self._data)
    
    def __setitem__(self, key, item):
        i = len(self._data)
        self._data = self._data + (item,)
        self._column_map[key] = i
        
    def __delitem__(self, key): raise NotImplementedError()
    def clear(self): raise NotImplementedError()
    def copy(self): raise NotImplementedError()
    
    def __iter__(self):
        for i in self._data:
            yield i
            
    def __contains__(self, key):
        return key in self._column_map
    
    def __str__(self):
        return "type:DataRow\n" + str(self.to_dict())
    
    def columns(self):
        return self._column_map.keys()
    iterkeys = keys = columns
    
    def values(self):
        return self._data
    itervalues = values

    def items(self):
        for k, i in self._column_map.iteritems():
            yield k, self._data[i]
    iteritems = items

    def has_column(self, column):
        return self._column_map.has_key(column)
    has_key = has_column
    
    def update(self, dict=None, **kwargs):
        for k, v in dict.items():
            self.__setitem__(k, v)
    
    def get(self, key, failobj=None):
        if not self.has_key(key):
            return failobj
        return self[key]
    
    def setdefault(self, key, failobj=None):
        if not self.has_key(key):
            self[key] = failobj
        return self[key]
    
    def pop(self, key, *args): raise NotImplementedError()
    def popitem(self): raise NotImplementedError()
    
    def to_dict(self):
        """return a dict"""
        d = {}
        for k, v in self.items():
            d[k] = v
        return d


class DataRowCollection(UserList):
    def __init__(self, rows, column_map):
        UserList.__init__(self, None)
        self._column_map = column_map
        self.data = [DataRow(r, self._column_map) for r in rows]
    
    def __iter__(self):
        for r in self.data:
            yield r
    
    def to_list(self):
        """return a list, and DataRow will be a dict"""
        return [r.to_dict() for r in self]